From fc7f08460324a469273c6c80383220cad1b56adc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20Elio=20Petten=C3=B2?= Date: Mon, 25 May 2020 13:47:25 +0100 Subject: freestyle_libre: extract non-encrypted metadata from encrypted messages. The sequence number and MAC are not actually encrypted, so they can be extracted as METADATA. --- reversing_tools/abbott/extract_freestyle.py | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/reversing_tools/abbott/extract_freestyle.py b/reversing_tools/abbott/extract_freestyle.py index e0ae66d..3efbc5a 100755 --- a/reversing_tools/abbott/extract_freestyle.py +++ b/reversing_tools/abbott/extract_freestyle.py @@ -10,6 +10,7 @@ import logging import sys import textwrap +import construct import usbmon import usbmon.chatter import usbmon.pcapng @@ -35,6 +36,13 @@ _UNENCRYPTED_TYPES = ( _ABBOTT_VENDOR_ID = 0x1A61 _LIBRE2_PRODUCT_ID = 0x3950 +_ENCRYPTED_MESSAGE = construct.Struct( + message_type=construct.Byte, + encrypted_message=construct.Bytes(64 - 1 - 4 - 4), + sequence_number=construct.Int32ul, + mac=construct.Int32ul, +) + def main(): if sys.version_info < (3, 7): @@ -155,10 +163,16 @@ def main(): message_metadata = [] if args.encrypted_protocol and message_type not in _UNENCRYPTED_TYPES: - # When expecting encrypted communication), we ignore the - # message_length and we keep it with the whole message. + # With encrypted communication, the length of the message is also encrypted, + # and all the packets use the full 64 bytes. So instead, we extract what + # metadata we can. + parsed = _ENCRYPTED_MESSAGE.parse(packet.payload) + message_metadata.extend( + [f"SEQUENCE_NUMBER={parsed.sequence_number}", f"MAC={parsed.mac:04x}"] + ) + message_type = f"x{message_type:02x}" - message = packet.payload[1:] + message = parsed.encrypted_message else: message_length = packet.payload[1] message_metadata.append(f"LENGTH={message_length}") -- cgit v1.2.3